package com.sh.src.test;


import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Map.Entry;


/**
 * 原生HttpClient工具类
 * @author yyj
 *
 */
public class HttpClients {
    private static final Logger LOGGER = LoggerFactory.getLogger(HttpClients.class);


    /**
     * post请求 传输json
     * @param httpUrl	请求url
     * @param jsonStr	json字符串
     * @param headerMap	请求头map
     * @return
     */
    public static String doPostJsonHeader(String httpUrl, String jsonStr, Map<String, String> headerMap , String cookie) throws Exception{

        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedWriter bw = null;
        BufferedReader br = null;
        String result = null;
        try {
            LOGGER.debug("Doing HTTP request: POST [{}]", httpUrl);
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间：15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间：60000毫秒
            connection.setReadTimeout(60000);

            // 默认值为：false，当向远程服务器传送数据/写数据时，需要设置为true
            connection.setDoOutput(true);
            // 默认值为：true，当前向远程服务读取数据时，设置为true，该参数可有可无
            connection.setDoInput(true);
            // 默认值为：true 设置false禁用缓存
            connection.setUseCaches(false);
            //获取session
            connection.setRequestProperty("Cookie", cookie);
//            connection.connect();
            // 根据headerMap设置请求头
            if (MapUtils.isNotEmpty(headerMap)) {
                Set<Entry<String, String>> entrySet = headerMap.entrySet();
                for (Entry<String, String> entry : entrySet) {
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            connection.setInstanceFollowRedirects(false);
            // 传输json数据
            if (jsonStr != null && !jsonStr.isEmpty()) {
                // 必须用字符流 不然在容器中会报json格式错误
                // 通过连接对象获取一个缓冲字符输出流
                bw = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),"UTF-8"));
                // 通过输出流对象将参数写出去/传输出去
                bw.write(jsonStr);
                bw.flush();
            }

            // 通过连接对象获取一个输入流，向远程读取
            if (connection.getResponseCode() == 200) {

                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            if (null != bw) {
                try {
                    bw.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            connection.disconnect();
        }
        return result;
    }

    public static String doGet(String httpUrl) throws Exception{

        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedWriter bw = null;
        BufferedReader br = null;
        String result = null;
        try {
            LOGGER.debug("Doing HTTP request: GET [{}]", httpUrl);
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("GET");
            // 设置连接主机服务器超时时间：15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间：60000毫秒
            connection.setReadTimeout(60000);

            // 默认值为：false，当向远程服务器传送数据/写数据时，需要设置为true
            connection.setDoOutput(true);
            // 默认值为：true，当前向远程服务读取数据时，设置为true，该参数可有可无
            connection.setDoInput(true);
            // 默认值为：true 设置false禁用缓存
            connection.setUseCaches(false);
//            connection.connect();
            // 根据headerMap设置请求头
            connection.setInstanceFollowRedirects(false);

            // 通过连接对象获取一个输入流，向远程读取
            if (connection.getResponseCode() == 200) {

                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            if (null != bw) {
                try {
                    bw.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            connection.disconnect();
        }
        return result;
    }

    public static String doPostJsonHeader(String httpUrl, String jsonStr, Map<String, String> headerMap) throws Exception{

        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedWriter bw = null;
        BufferedReader br = null;
        String result = null;
        try {


            LOGGER.debug("Doing HTTP request: POST [{}]", httpUrl);
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间：15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间：60000毫秒
            connection.setReadTimeout(60000);

            // 默认值为：false，当向远程服务器传送数据/写数据时，需要设置为true
            connection.setDoOutput(true);
            // 默认值为：true，当前向远程服务读取数据时，设置为true，该参数可有可无
            connection.setDoInput(true);
            // 默认值为：true 设置false禁用缓存
            connection.setUseCaches(false);
            // 根据headerMap设置请求头
            if (MapUtils.isNotEmpty(headerMap)) {
                Set<Entry<String, String>> entrySet = headerMap.entrySet();
                for (Entry<String, String> entry : entrySet) {
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            // 传输json数据
            if (jsonStr != null && !jsonStr.isEmpty()) {
                // 必须用字符流 不然在容器中会报json格式错误
                // 通过连接对象获取一个缓冲字符输出流
                bw = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),"UTF-8"));
                // 通过输出流对象将参数写出去/传输出去
                bw.write(jsonStr);
                bw.flush();
            }

            // 通过连接对象获取一个输入流，向远程读取
            if (connection.getResponseCode() == 200) {

                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
            }
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            if (null != bw) {
                try {
                    bw.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            // 断开与远程地址url的连接
//            String cookieVal = connection.getHeaderField("Set-Cookie");
//            System.out.println(cookieVal+" ; Domain=10.20.94.3; HttpOnly;");
            connection.disconnect();
        }
        return result;
    }


    /**
     * post请求 传输json
     * @param httpUrl	请求url
     * @param jsonStr	json字符串
     * @param headerMap	请求头map
     * @return
     */
    public static String getCookie(String httpUrl, String jsonStr, Map<String, String> headerMap) throws Exception{
        String  cookie = "";


        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedWriter bw = null;
        BufferedReader br = null;
        String result = null;
        try {
            LOGGER.debug("Doing HTTP request: POST [{}]", httpUrl);
            CookieManager manager = new CookieManager();
            manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
            CookieHandler.setDefault(manager);
            URL url = new URL(httpUrl);
            // 通过远程url连接对象打开连接
            connection = (HttpURLConnection) url.openConnection();
            // 设置连接请求方式
            connection.setRequestMethod("POST");
            // 设置连接主机服务器超时时间：15000毫秒
            connection.setConnectTimeout(15000);
            // 设置读取主机服务器返回数据超时时间：60000毫秒
            connection.setReadTimeout(60000);

            // 默认值为：false，当向远程服务器传送数据/写数据时，需要设置为true
            connection.setDoOutput(true);
            // 默认值为：true，当前向远程服务读取数据时，设置为true，该参数可有可无
            connection.setDoInput(true);
            // 默认值为：true 设置false禁用缓存
            connection.setUseCaches(false);
//            //获取session
            // 根据headerMap设置请求头
            if (MapUtils.isNotEmpty(headerMap)) {
                Set<Entry<String, String>> entrySet = headerMap.entrySet();
                for (Entry<String, String> entry : entrySet) {
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            // URLConnection.setInstanceFollowRedirects是成员函数，仅作用于当前函数
            connection.setInstanceFollowRedirects(false);
            url.openConnection();
//            url.getContent();
            CookieStore cookieJar = manager.getCookieStore();
            List<HttpCookie> cookies = cookieJar.getCookies();
            System.out.println(cookies.size()+"xxxxxxxx");
            for (HttpCookie cookie1 : cookies) {
                System.out.println(cookie1);
            }

            // 传输json数据
            if (jsonStr != null && !jsonStr.isEmpty()) {
                // 必须用字符流 不然在容器中会报json格式错误
                // 通过连接对象获取一个缓冲字符输出流
                bw = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),"UTF-8"));
                // 通过输出流对象将参数写出去/传输出去
                bw.write(jsonStr);
                bw.flush();
            }

            // 通过连接对象获取一个输入流，向远程读取
            if (connection.getResponseCode() == 200) {

                is = connection.getInputStream();
                // 对输入流对象进行包装:charset根据工作项目组的要求来设置
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

                StringBuffer sbf = new StringBuffer();
                String temp = null;
                // 循环遍历一行一行读取数据
                while ((temp = br.readLine()) != null) {
                    sbf.append(temp);
                    sbf.append("\r\n");
                }
                result = sbf.toString();
                System.out.println(result);
            }
        } finally {
            // 关闭资源
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            if (null != bw) {
                try {
                    bw.close();
                } catch (IOException e) {
                    LOGGER.error(e.getMessage() +"：{}",e);
                }
            }
            connection.disconnect();
        }
        return cookie;
    }


    public static void main(String[] args) {

        for(int i=0;i<20;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    while(true){
                        String httpUrl ="http://139.196.148.117:6001/user/add";
                        String jsonStr = "{\"username\":\"xpc1\",\"password\":\"2575111111111111111197\",\"sex\":1,\"deleted\":0,\"updateTime\":\"2022-07-14T02:59:11.000+00:00\",\"createTime\":\"2022-07-14T02:59:11.000+00:00\"}";
                        try {
                            for (int i = 0; i < Integer.MAX_VALUE; i++) {
                                Map<String, String> headerMap = new HashMap<String, String>();
                                headerMap.put("Content-Type", "application/json");
                                HttpClients.getCookie(httpUrl, jsonStr, headerMap);
                            }
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }




    }
}
